home *** CD-ROM | disk | FTP | other *** search
- /*{{{}}}*/
- /*{{{ #includes*/
- #include <ctype.h>
- #include <string.h>
- #include <stdlib.h>
- #include <stdio.h>
-
- #define PARSEASM_C
- #define CODE_LG_ARRAY
-
- #include "keybind.h"
- #include <h/codelg.h>
- #include <lib/ori_add_lib.h>
- /*}}} */
-
- /*{{{ typedef ocl_label*/
- typedef struct ocl_label
- { char *name;
- TOKEN *val;
- struct ocl_label *next;
- } ocl_label;
- /*}}} */
- /*{{{ variables*/
- ocl_label *used_labels;
- ocl_label *def_labels;
- TOKEN *start_buff;
- /*}}} */
-
- /*{{{ create_label*/
- private void create_label(ocl_label **labels,TOKEN *buff,unsigned char *str)
- { ocl_label *x;
-
- x=kbd_malloc(sizeof(ocl_label)+ustrlen(str)+1);
- x->next= *labels;
- *labels=x;
- x->val=buff;
- strcpy(x->name=(char*)(x+1),(char*)str);
- }
- /*}}} */
- /*{{{ get_ind_arg*/
- private boolean get_ind_arg(TOKEN **buff_p)
- { tokens token;
- int fak;
- int add=0;
-
- /*{{{ maybe get offset*/
- while ((token=get_full_token())==ADD)
- { int add_fak=1;
-
- switch (get_full_token())
- { case MINUS:
- if (get_full_token()!=NUMBER)
- default:
- goto error_int_arg;
- add_fak= -1;
- case NUMBER:
- add+=add_fak*tk_val;
- break;
-
- }
- }
- /*}}} */
- fak=1;
- switch (token)
- { case MINUS:
- if (get_full_token()!=NUMBER)
- goto error_int_arg;
- fak= -1;
- case NUMBER:
- *(*buff_p)++=tk_val*fak+add;
- return(False);
- case NAME:
- { int x;
-
- if ((x=name2msg(tk_string))>=0)
- { *(*buff_p)++=x*fak+add;
- return(False);
- }
- goto error_int_arg;
- }
- case BEGIN:
- { unsigned char hide_var[NAME_LG];
-
- /*{{{ get name for hidden variable*/
- if (get_full_token()!=NAME) goto error_int_arg;
- hide_var[0]='(';
- ustrcpy(hide_var+1,tk_string);
- if (get_full_token()!=END) goto error_int_arg;
- strcat((char*)hide_var,")");
- ustrcpy(tk_string,hide_var);
- /*}}} */
- /*{{{ look for this hidden variable*/
- { VARS_LIST const *x;
-
- for (x=var_list;;)
- if (!x)
- goto error_int_arg;
- else if (x->var_name && !ustrcmp(x->var_name,hide_var))
- break;
- else
- x=x->next;
- tk_var=x;
- }
- /*}}} */
- }
- case VARIABLE:
- *(*buff_p)++=tk_var->no+add;
- return(False);
- default:
- error_int_arg:
- m_exit(M_NOVAR);
- }
- }
- /*}}} */
- /*{{{ get_char_arg*/
- private TOKEN *get_char_arg(TOKEN *buff)
- {
- switch (get_full_token())
- { case NUMBER:
- *buff++=tk_val;
- return(buff);
- case MACRO:
- if (ustrlen(tk_string)!=1)
- goto char_arg_error;
- *buff++=tk_string[0];
- return(buff);
- default:
- char_arg_error:
- m_exit(M_NOADDCOUNTER);
- }
- }
- /*}}} */
- /*{{{ get_add_arg*/
- private TOKEN *get_add_arg(TOKEN *buff)
- { tokens token;
- int add=0;
-
- /*{{{ maybe get offset*/
- while ((token=get_full_token())==ADD)
- { int fak=1;
-
- switch (get_full_token())
- { case MINUS:
- if (get_full_token()!=NUMBER)
- default:
- goto ad_arg_error;
- fak= -1;
- case NUMBER:
- add+=fak*tk_val;
- break;
-
- }
-
- }
- /*}}} */
- switch (token)
- {
- /*{{{ NUMBER use offset directly*/
- case NUMBER:
- *buff++=tk_val;
- return(buff);
- /*}}} */
- /*{{{ NAME use label, maybe mark for backpatching*/
- case NAME:
- { ocl_label *x;
-
- for (x=def_labels;x && strcmp(x->name,(char*)tk_string);x=x->next);
- if (x)
- { *buff=x->val-buff-1+add;
- }
- else
- { create_label(&used_labels,buff,tk_string);
- *buff=start_buff-buff+1+add;
- }
- return(buff+1);
- }
- /*}}} */
- default:
- ad_arg_error:
- m_exit(M_NOADDCOUNTER);
- }
- }
- /*}}} */
- /*{{{ parse_asm*/
- public TOKEN *parse_asm(TOKEN *buff,unsigned char *name)
- { tokens token;
-
- used_labels=0;
- def_labels=0;
- start_buff=buff;
- if (verbose_level>0) fprintf(stderr,M_ASM_1,name);
- begin_parse();
- do
- /*{{{ handle a statement*/
- { check_length(buff);
- token=get_full_token();
- switch (token)
- {
- /*{{{ insert opcode*/
- case OPCODE:
- *buff++=tk_key->num;
- continue;
- /*}}} */
- /*{{{ single TOKEN macro*/
- case OPERATION:
- if (tk_operation->length!=1) goto asm_error;
- *buff++ = *(tk_operation->ops);
- continue;
- /*}}} */
- /*{{{ eval, call parse_macro as subroutine call*/
- case EVAL:
- { TOKEN *call;
- TOKEN *jmp;
- boolean foo;
-
- buff=generate_jmp(M_CALL,call=buff,buff);
- buff=generate_jmp(M_JMP,jmp=buff,buff);
- generate_jmp(M_CALL,call,buff);
- if (!(buff=opt_parse_macro(call=buff,0,&foo,False,!demand,True))) return(0);
- *buff++=M_END_MACRO;
- generate_jmp(M_JMP,jmp,buff);
- break;
- }
- /*}}} */
- /*{{{ number*/
- case NUMBER:
- *buff++=tk_val;
- break;
- /*}}} */
- /*{{{ string*/
- case MACRO:
- { TOKEN *x;
-
- for (x=tk_macro;*x;*buff++ = *x++);
- break;
- }
- /*}}} */
- /*{{{ NAME -> ocl-asm-statement or label*/
- case NAME:
- { KEYNAME const *a;
-
- if ((a=name2asm(tk_string)))
- /*{{{ asm-command*/
- { *buff++=a->num;
- switch (cmd_type[a->num-O_NOP])
- { case COM_II:
- if (get_ind_arg(&buff)) return(0);
- case COM_I:
- if (get_ind_arg(&buff)) return(0);
- case COM:
- break;
- case COM_C:
- if (!(buff=get_char_arg(buff))) return(0);
- break;
- case COM_A:
- if (!(buff=get_add_arg(buff))) return(0);
- break;
- case COM_IIP:
- if (get_ind_arg(&buff)) return(0);
- case COM_IP:
- if (get_ind_arg(&buff)) return(0);
- case COM_P:
- if (!(buff=get_message(buff))) return(0);
- break;
- }
- continue;
- }
- /*}}} */
- else if (tk_string[0]=='.')
- /*{{{ label*/
- { ocl_label *x,*y;
-
- /*{{{ already defined?*/
- for
- ( x=def_labels;
- x && strcmp(x->name,(char*)tk_string+1);
- x=x->next
- );
- if (x)
- if (x->val!=buff)
- /*{{{ error, duplicate definition*/
- m_exit(M_DUPDEF);
- /*}}} */
- else
- /*{{{ same adress used, so ok*/
- break;
- /*}}} */
- /*}}} */
- /*{{{ backpatch*/
- for (y=0,x=used_labels;x;)
- if (strcmp(x->name,(char*)tk_string+1))
- { y=x;
- x=x->next;
- }
- else
- { *(x->val)+=buff-start_buff-2;
- if (y)
- { y->next=x->next;
- kbd_free(x);
- x=y->next;
- }
- else
- { used_labels=x->next;
- kbd_free(x);
- x=used_labels;
- }
- }
- /*}}} */
- /*{{{ define new*/
- create_label(&def_labels,buff,tk_string+1);
- /*}}} */
- break;
- }
- /*}}} */
- else
- goto asm_error;
- }
- /*}}} */
- /*{{{ ) -> ready*/
- case END:
- break;
- /*}}} */
- /*{{{ default: error*/
- default:
- asm_error:
- m_exit(M_NOMSTRING);
- /*}}} */
- }
- }
- /*}}} */
- while (token!=END);
- if (used_labels)
- { error_po();
- fprintf(stderr,F_ASM_LM,used_labels->name);
- return(0);
- }
- while (def_labels)
- { ocl_label *x;
-
- x=def_labels;
- def_labels=x->next;
- kbd_free(x);
- }
- return(buff);
- }
- /*}}} */
-